package com.pas.book;

import com.java4ever.apime.io.GZIP;

import java.io.IOException;
import java.io.InputStream;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.game.GameCanvas;
import javax.microedition.lcdui.game.Sprite;
import javax.microedition.midlet.MIDlet;

public class TextCanvas extends GameCanvas implements Runnable, CommandListener {
    private static final Command CMD_EXIT = new Command("Exit", Command.EXIT, 0);
    private static final Command CMD_DRAW = new Command("Refresh", Command.SCREEN, 0);

    private final Display display;
    private final MIDlet midlet;
    private final TextDrawer textDrawer;
    private int bgColor;
    private char[] text;

    protected TextCanvas(Display display, MIDlet midlet) {
        super(false);
        this.display = display;
        this.midlet = midlet;
        this.bgColor = ColorUtil.gray(1.0);
        addCommand(CMD_EXIT);
        addCommand(CMD_DRAW);
        setFullScreenMode(true);
        textDrawer = new TextDrawer(new RasterFont("tahoma"));
    }

    public void run() {
        setCommandListener(this);
        display.setCurrent(this);
        clean(getGraphics());
//        String text = "simple java mipd application for reading texts on mobile phone";
    }

    private void clean(Graphics g) {
        g.setColor(bgColor);
        g.fillRect(g.getClipX(), g.getClipY(), g.getClipX() + g.getClipWidth(), g.getClipY() + g.getClipHeight());
    }

    protected void keyPressed(int key) {
        int action = getGameAction(key);
        switch (action) {
            case UP:
                bgColor = ColorUtil.brighter(bgColor, 32);
                if (Utils.DEBUG) Utils.debug("bgColor=" + (bgColor & 0xff));
                drawText();
                break;
            case DOWN:
                bgColor = ColorUtil.darker(bgColor, 32);
                if (Utils.DEBUG) Utils.debug("bgColor=" + (bgColor & 0xff));
                drawText();
                break;
        }
    }

    private char[] getText() {
        if (text != null) return text;
        try {
            InputStream in = getClass().getResourceAsStream("/text.txt");
            int sz = in.available();
            byte[] buf = new byte[sz];
            in.read(buf);
            in.close();
            return new String(CharCode.Win1251ToUnicode(buf)).toCharArray();
//            return new String(buf);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    private char[] getTextGZ() {
        if (text != null) return text;
        try {
            InputStream in = getClass().getResourceAsStream("/text.txt.gz");
            int sz = in.available();
            byte[] buf = new byte[sz];
            in.read(buf);
            in.close();
            buf = GZIP.inflate(buf);
            return new String(CharCode.Win1251ToUnicode(buf)).toCharArray();
//            return new String(buf);
        } catch (IOException e) {
            throw new RuntimeException(e.getMessage());
        }
    }

    protected void showNotify() {
        text = getText();
        drawText();
    }

    private void drawText() {
        Graphics g = getGraphics();
        clean(g);
        Image img = Image.createImage(getHeight() - 2, getWidth());
        Graphics ig = img.getGraphics();
        clean(ig);
        RasterFont font = textDrawer.getFont();
        int fontHeight = font.getHeight() - 3;
        int imgHeight = img.getHeight();
        int maxWidth = img.getWidth();

        int first = 0;
        for (int y = 0; y < imgHeight; y += fontHeight) {
            int cnt = guessCharsCount(first, maxWidth);
            textDrawer.draw(ig, text, first, cnt, 0, y);
            first += cnt;
        }
        img = Image.createImage(img, 0, 0, img.getWidth(), img.getHeight(), Sprite.TRANS_ROT90);
        g.drawImage(img, 0, 1, Graphics.TOP | Graphics.LEFT);
        flushGraphics();
    }

    private int guessCharsCount(int offset, int maxWidth) {
        RasterFont font = textDrawer.getFont();
        int w = 0, n = offset;
        do {
            char ch = text[n++];
            if (ch == '\n' || ch == '\r') break;
            w += font.getWidth(ch);
            if (w > maxWidth) {
                return n - 1 - offset;
            }
        } while (n < text.length);
        return n - offset;
    }

    public void commandAction(Command command, Displayable displayable) {
        System.out.println("command = " + command);
        System.out.println("displayable = " + displayable);
        if (CMD_DRAW.equals(command)) {
            drawText();
        } else if (CMD_EXIT.equals(command)) {
            midlet.notifyDestroyed();
        }
    }
}
